<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/1/4/004
 * Time: 22:36
 */

namespace backend\models\forms;


use backend\models\AdminRole;
use backend\models\AdminUser;
use backend\models\AdminUserRole;
use common\models\AdminUserInfo;
use common\models\Captchas;
use common\models\CollectAccount;
use common\models\DataErrorCode;
use common\models\game\SeoidDiamond;
use common\services\Messenger;
use common\services\ToolService;
use common\utils\CommonFun;
use yii\base\Exception;
use yii\base\Model;
use yii\captcha\CaptchaValidator;
use yii\db\ActiveRecord;
class UserForm extends Model
{
    public $uname;//用户名
    public $password;//密码
    public $phone;//手机号码
    public $email;//邮箱
    public $promo_code;//推广码
    public $agent;//代理商
    public $job;//职位
    public $user_icon;//头像
    public $code;//短信验证码
    public $comment;//备注
    public $error_times;//错误次数
    public $status;//状态
    public $captcha;//图形验证码
    public $created_by;//创建人

    public function rules()
    {
        return [
            //uname rules
            ['uname', 'required', 'on' => ['create', 'login', 'login_code']],
            ['uname', 'validateUser', 'on' => ['login', 'login_code']],
            ['uname', 'uniqueUser', 'on' => ['create','update']],
            ['uname', 'string', 'min' => 4, 'on' => ['create', 'update']],
            ['uname', 'filter', 'filter' => 'trim'],
            [['uname'], 'match', 'pattern' => '/^[A-Za-z0-9_]+$/u', 'message' => "只能是数字、字母、下划线", 'on' => ['create','update']],

            //password rules
            ['password', 'required', 'on' => ['create', 'login']],
            ['password', 'filter', 'filter' => 'trim'],
            ['password', 'string', 'length' => [5, 24], 'on' => ['create', 'update']],
            ['password', 'validateLoginPwd', 'on' => 'login'],

            //promo_code rules
            ['promo_code', 'match', 'pattern' => '/^[A-Z0-9_]+$/u', 'message' => "只能是大写字母和数字", 'on' => ['create','update']],
            ['promo_code', 'validateRequired', 'on' => ['create']],
            ['promo_code', 'validateUnique','on' => ['create']],
            ['promo_code', 'string'],

            //phone rules
            //['phone', 'required', 'on' => ['create', 'update']],
            //['phone', 'match', 'pattern' => '/^0?(13|14|15|17|18)[0-9]{9}$/', 'message' => '不是有效的手机号码', 'on' => ['create', 'update']],
//            ['phone', 'string', 'max' => 11],

            //code rules
//            ['code', 'string'],
            //['code', 'validateCode', 'on' => ['create', 'update']],
            //['code', 'required', 'on' => ['create', 'update', 'login_code']],
            //['code', 'validateLoginCode', 'on' => ['login_code']],

            //captcha rules
            ['captcha','required','on'=>['login']],
            ['captcha','string','on'=>['login']],
            ['captcha','validateCaptcha','on'=>['login']],

            //other rules
            [['user_icon','comment','agent'], 'string'],
            [['job'], 'integer'],
            ['job', 'required', 'on' => ['create']],
            ['agent','validateGroupRequired'],
            ['status','integer'],
            ['created_by','string'],
            ['created_by','required','on'=>['create']],
        ]; // TODO: Change the autogenerated stub
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'uname' => '用户名',
            'password' => '密码',
            'phone' => '手机号码',
            'email' => '邮箱',
            'promo_code' => '推广号',
            'comment' => '备注',
            'user_icon' => '头像',
            'agent' => '代理商',
            'job' => '职位',
            'code' => '验证码',
            'captcha' => '验证码',
            'created_by' => '创建人',
        ];
    }

    public function validateCaptcha($attribute)
    {
        $f = file_get_contents(dirname(__FILE__).'/../../runtime/logs/authcode.log');
        $result = explode('|',$f);
        $count = count($result);

        if($count>0) {
            $result1 = empty($result[$count - 2])?null:json_decode($result[$count - 2])->captcha;
            $result2 = empty($result[$count - 3])?null:json_decode($result[$count - 3])->captcha;
            if ($result1 !== $this->captcha && $result2 !== $this->captcha) {
                $this->addError($attribute, '验证码错误');
            }
        }else{
            $this->addError($attribute, '验证码错误');
        }

    }

    public function validateGroupRequired($attribute)
    {
        $model = AdminRole::find()->filterWhere(['id'=>$this->job])->one();
        $user_info = AdminUserInfo::find()->filterWhere(['promo_code'=>$this->agent])->one();
        if(!in_array($model->name,['超级管理员','管理员','总代理','特殊管理员']) && empty($this->agent)){
            $this->addError($attribute, '代理商不能为空');
        }elseif(empty($user_info)){
            $this->addError($attribute,'代理商不存在');
        }
    }

    public function validateUnique($attribute)
    {
        if($model = AdminUserInfo::find()->filterWhere(['promo_code'=>$this->promo_code])->one()){
            $this->addError($attribute, '推广号已占用');
        }
    }

    public function validateRequired($attribute)
    {
        $model = AdminRole::find()->filterWhere(['id'=>$this->job])->one();
        if($model->is_promo_code == 1){
            if(empty($this->promo_code)) {
                $this->addError($attribute, '推广号不能为空');
            }
        }
    }

    /**
     * 图形验证码校验
     * @param unknown $attribute
     */
    public function captchaDIY($attribute)
    {
        $verifyCode = $this->verifyCode;

        $caprcha = new CaptchaValidator(['captchaAction'=>'site/captcha']);

        if(!$caprcha->validate($verifyCode)){

            $this->addError($attribute, '验证码不正确');

        }
    }

    /**
     * 验证登录用户是否存在
     */
    public function validateUser($attribute)
    {
        $model = AdminUser::findByUsername($this->uname);
        if (empty($model)) {
            $this->addError($attribute, '该用户不存在');
        }else if($model->status == -10){
            $this->addError($attribute, '该用户被封禁，无法登陆，请联系管理员！');
        }
    }

    /**
     * 验证登录密码
     * @param $attribute
     */
    public function validateLoginPwd($attribute)
    {
        if (\Yii::$app->session->isActive) {
            \Yii::$app->session->open();
        }
        $session = \Yii::$app->session;
        $error_time = $session->get($this->uname);
        if (empty($error_time)) {
            $session->set($this->uname, 0);
        }
        $model = AdminUser::findByUsername($this->uname);


        if(!empty($model)) {
            if ($error_time != 3) {
                if (!empty($this->password) && (!empty($model) && $model->status != -10 )) {
                    if (AdminUser::validatePassword($model, $this->password) != true || $model->status != 10) {
                        if($model->id_parent == 0){
                            $this->addError($attribute, "密码错误");
                        }else {
                            switch ($error_time) {
                                case 0:
                                    $session->set($this->uname, 1);
                                    break;
                                case 1:
                                    $session->set($this->uname, 2);
                                    break;
                                case 2:
                                    $session->set($this->uname, 3);
                                    break;

                            }
                            $error_time = $session->get($this->uname);
                            if (!empty($model) && $model->status == 20) {
                                unset($_SESSION[$this->uname]);
                                $this->addError($attribute, "密码错误三次，已被冻结，请联系管理员给你解冻");
                            } else if ($error_time == 3 && $model->status != -10) {
                                $model->status = 20;
                                $model->save();
                                $this->addError($attribute, "密码错误三次，已被冻结，请联系管理员给你解冻");
                            } else {
                                $this->addError($attribute, "密码错误{$error_time}次");
                            }
                        }
                    }
                }
            } else {
                $this->addError($attribute, "密码错误三次，已被冻结，请联系管理员给你解冻");
            }
        }
    }

    /**
     * 判断用户是否被注册
     * @param $attribute
     */
    public function uniqueUser($attribute)
    {
        $model = AdminUser::findByUsername($this->uname);
        if (!empty($model)) {
            $this->addError($attribute, '该用户名已经被注册');
        }
    }

    /**
     * 登录验证码校验
     * @param unknown $attribute
     */
    public function validateLoginCode($attribute)
    {
        $user = AdminUser::findByUsername($this->uname);
        $vStr = $this->code;
        $phone = $user->userInfo->phone;
        $error = '验证码错误';
        $ifvalidated = false;
        $message = Captchas::find()->where(['phone' => $phone, 'status' => 10, 'id_user' => $user->id])->orderBy('id DESC')->one();
        if ($message) {
            //30*60秒过期
            if (time() - $message->created_at < 1800) {
                $ifvalidated = $vStr == $message->code;
                $message->status = 0;
                $message->save();
            } else {
                $error = '验证码过期，请重新获取';
            }
        } else {
            $error = '验证码无效请求，请重新获取';
        }
        if (!$ifvalidated) {
            $this->addError($attribute, $error);
        }
    }

    /**
     * 注册验证码校验
     * @param unknown $attribute
     */
    public function validateCode($attribute)
    {
        $vStr = $this->code;
        $phone = $this->phone;
        $error = '验证码错误';
        $ifvalidated = false;
        $message = Captchas::find()->where(['phone' => $phone, 'status' => 10, 'id_user' => \Yii::$app->user->id])->orderBy('id DESC')->one();
        if ($message) {
            //30*60秒过期
            if (time() - $message->created_at < 1800) {
                $ifvalidated = $vStr == $message->code;
                $message->status = 0;
                $message->save();
            } else {
                $error = '验证码过期，请重新获取';
            }
        } else {
            $error = '验证码无效请求，请重新获取';
        }
        if (!$ifvalidated) {
            $this->addError($attribute, $error);
        }
    }

    /**
     * 密码登录
     */
    public function login()
    {
        $user = AdminUser::findByUsername($this->uname);
        if (AdminUser::login($user->uname, $user->password)) {
            unset($_SESSION[$user->uname]);

            AdminUser::updateAll(
                ['last_ip' => CommonFun::getClientIp(),'status'=>10],
                ['uname' => $user->uname]
            );
            return true;
        } else {
            return false;
        }
    }

    public function getRole()
    {
        $model = AdminRole::findOne(['id'=>$this->job]);
        return $model->is_promo_code;
    }

    /**
     * 保存用户
     * @return bool
     * @throws \yii\db\Exception
     */
    public function saveUser()
    {
        $message = new Messenger();
        $connection = \Yii::$app->getDb('db');
        $transaction = $connection->beginTransaction();
        $validate = true;

        $user = new AdminUser();
        $user->uname = $this->uname;
        $user->current_password = $this->password;
        $user->password = $this->password;
        $user->status = 10;
        $user->is_online = 'n';

        if (empty($this->agent)) {
            $user->id_parent = AdminUser::find()->filterWhere(['id_parent' => 0])->one()->id;
        } else {
            $user->id_parent = AdminUserInfo::find()->filterWhere(['promo_code' => $this->agent])->one()->user_id;
        }
        $user->create_user = $this->created_by;
        $user->create_date = date('Y-m-d H:i:s');
        $user->update_user = $this->created_by;
        $user->update_date = date('Y-m-d H:i:s');
        $validate = $validate && $user->validate() && $user->save();
        if (!$validate) {
            $error = null;
            foreach ($user->errors as $value) {
                $error .= $value[0] . ',';
            }
            $message -> status = 0;
            $message -> message = $error."----\n";
        }

        $user_role = new AdminUserRole();
        $user_role->user_id = $user->id;
        $user_role->role_id = $this->job;
        $user_role->create_user = $this->created_by;
        $user_role->create_date = date('Y-m-d H:i:s');
        $user_role->update_user = $this->created_by;
        $user_role->update_date = date('Y-m-d H:i:s');
        $validate = $validate && $user_role->validate() && $user_role->save();
        if (!$validate) {
            $error = null;
            foreach ($user->errors as $value) {
                $error .= $value[0] . ',';
            }
            $message -> status = 0;
            $message -> message = $error."----\n";
        }

        if ($this->getRole() == 1) {
            $seo_diamond = new SeoidDiamond();

            $data['SeoidDiamond'] = [
                'seoid' => $this->promo_code,
                'diamond' => 0,
                'status' => 0,
            ];

            $validate = $seo_diamond->load($data) && $seo_diamond->validate() && $seo_diamond->save();
            if (!$validate) {
                $error = null;
                foreach ($seo_diamond->errors as $value) {
                    $error .= $value[0] . ',';
                }
                $message -> status = 0;
                $message -> message = $error."----\n";
            }
        }
        if ($user->parent->id_parent == 0) {
            $collect_model = new CollectAccount();
            $collect_model->id_user = $user->id;
            $collect_model->role = '总代理';
            $collect_model->promo_code = $this->promo_code;
            if ($collect_model->validate() && $collect_model->save()) {
            } else {
                $error = null;
                foreach ($user->errors as $value) {
                    $error .= $value[0] . ',';
                }
                $message -> status = 0;
                $message -> message = $error."----\n";
            }

        }

        if ($validate) {
            $model = AdminUser::findOne(['uname' => $this->created_by]);
            $user_info = new AdminUserInfo();
            $user_info->phone = $this->phone;
            $user_info->user_id = $user->id;
            $user_info->email = $this->email;
            $user_info->promo_code = $this->promo_code;
            $user_info->user_icon = $this->user_icon;
            $user_info->comment = $this->comment;
            $user_info->created_by = $model->id;
            $validate = $validate && $user_info->validate() && $user_info->save();
            if (!$validate) {
                $error = null;
                foreach ($user->errors as $value) {
                    $error .= $value[0] . ',';
                }
                $message -> status = 0;
                $message -> message .= $error."----\n";
            }
            $transaction->commit();
        } else {
            $transaction->rollBack();

        }
        return $validate;
    }

    public function updateUser($id)
    {
        $connection = \Yii::$app->getDb('db');
        $transaction = $connection->beginTransaction();
        $validate = true;

        $user = AdminUser::find()->filterWhere(['id' => $id])->one();

        $user->current_password = empty($this->password) ? null : $this->password;
        $user->update_user = $this->created_by;
        $user->update_date = date('Y-m-d H:i:s');
        $user->status = $this->status;
        $validate = $validate && $user->validate() && $user->save();
        if(!$validate){
            $error = null;
            foreach ($user->errors as $value){
                $error .= $value[0].',';
            }
            throw new Exception($error);
        }

        $user_info = AdminUserInfo::find()->filterWhere(['user_id'=>$id])->one();
        $user_info->email = $this->email;
        $user_info->user_icon = $this->user_icon;
        $user_info->comment = $this->comment;
        if(!empty($this->agent)) {
            $user_info->group = $this->agent;
        }
        if(!empty($this->job)) {
            $user_info->job = $this->job;
        }
        if(!empty($this->promo_code)) {
            $user_info->promo_code = $this->promo_code;
        }
        $validate = $validate && $user_info->validate() && $user_info->save();
        if(!$validate){
            $error = null;
            foreach ($user->errors as $value){
                $error .= $value[0].',';
            }
            throw new Exception($error);
        }

        $role = AdminUserRole::findOne(['user_id'=>$id]);
        $role -> role_id = empty($this->job)?$role->role_id:$this->job;
        $validate = $validate && $role->validate() && $role->save();
        if(!$validate){
            $error = null;
            foreach ($user->errors as $value){
                $error .= $value[0].',';
            }
            throw new Exception($error);
        }

        if ($validate) {
            $transaction->commit();
        } else {
            $transaction->rollBack();
        }

        return $validate;
    }

}